package com.x.mvp.widget.popupmenu;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;

import com.x.mvp.R;
import com.x.mvp.base.recycler.RecyclerAdapter;
import com.x.mvp.base.recycler.RecyclerViewHolder;
import com.x.mvp.widget.DividerItemDecoration;

import java.util.List;


public abstract class CheckboxGroupPopupWindow<D, VH extends CheckboxGroupPopupWindow.CheckboxHolder<D>> implements RecyclerAdapter.OnItemClickListener<D> {
    protected PopupWindow popupWindow;
    private RecyclerView recyclerView;
    private CheckboxGroupAdapter adapter;
    private D selectedItem;
    private int spanSize = 3;

    private Object cookie;

    onItemCheckedListener<D> onItemCheckedListener;

    public CheckboxGroupPopupWindow(Context context) {
        initPopup(context, getLayoutId());
    }

    public CheckboxGroupPopupWindow(Context context, CheckboxGroupPopupWindow.onItemCheckedListener<D> onItemCheckedListener) {
        initPopup(context, getLayoutId());
        this.onItemCheckedListener = onItemCheckedListener;
    }

    public CheckboxGroupPopupWindow.onItemCheckedListener<D> getOnItemCheckedListener() {
        return onItemCheckedListener;
    }

    public void setData(List<D> data) {
        if (adapter != null) {
            adapter.replaceAll(data);
        }
    }

    public void setCookie(Object cookie) {
        this.cookie = cookie;
    }

    public Object getCookie() {
        return cookie;
    }

    public void showAsDropDown(View parent) {
        popupWindow.showAsDropDown(parent, 0, 0);
    }

    protected void onShowCheckbox() {

    }

    protected int getLayoutId() {
        return R.layout.pop_up_window;
    }

    private void initPopup(Context context, int layoutId) {
        View maimView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(layoutId, null);
        recyclerView = (RecyclerView) maimView.findViewById(R.id.recycler_view);
        initRecyclerView(context);
        initPopupWindow(maimView);
        maimView.setOnClickListener(view -> popupWindow.dismiss());
    }

    protected void initPopupWindow(View parent) {
        popupWindow = new PopupWindow(parent, ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        popupWindow.setOutsideTouchable(true);
        popupWindow.setFocusable(true);
        popupWindow.setAnimationStyle(R.style.SlideRightAnim);
    }

    private void initRecyclerView(Context context) {
        this.recyclerView.setItemAnimator(new DefaultItemAnimator());
        this.recyclerView.setLayoutManager(getGridLayoutManager(context));
        DividerItemDecoration dividerItemDecoration = getDividerItemDecoration(context);
        if (dividerItemDecoration != null) {
            recyclerView.addItemDecoration(dividerItemDecoration);
        }
        adapter = new CheckboxGroupAdapter(recyclerView);
        adapter.setOnItemClickListener(this);
        recyclerView.setAdapter(adapter);
    }

    protected DividerItemDecoration getDividerItemDecoration(Context context) {
        return null;
    }

    @Override
    public void onItemClick(View view, D data, int position) {
        if (data != selectedItem) {
            selectedItem = data;
            adapter.notifyDataSetChanged();
            onItemCheckedListener.onItemChecked(position, data);
        }
        popupWindow.dismiss();
    }

    protected RecyclerView.LayoutManager getGridLayoutManager(Context context) {
        GridLayoutManager manager = new GridLayoutManager(context, spanSize);
        manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                return isCheckboxGroupItem(position) ? manager.getSpanCount() : 1;
            }
        });
        return manager;
    }

    public void setSpanSize(int spanSize) {
        this.spanSize = spanSize;
        if (adapter != null) {
            adapter.notifyDataSetChanged();
        }
    }

    public void setItemChecked(int position) {
        if (adapter.getData() != null && position < adapter.getData().size()) {
            selectedItem = adapter.getData().get(position);
        }
        adapter.notifyDataSetChanged();
    }

    public void setItemChecked(D item) {
        if (adapter.getData() != null && adapter.getData().contains(item)) {
            selectedItem = item;
        }
        adapter.notifyDataSetChanged();
    }

    public D getSelectedItem() {
        return selectedItem;
    }

    protected abstract VH createViewHolder(View itemView);

    protected abstract int getCheckBoxLayoutID();

    protected abstract int getCheckBoxGroupLayoutID();

    protected abstract boolean isCheckboxGroupItem(int index);

    protected abstract int checkboxGroupCount();

    class CheckboxGroupAdapter extends RecyclerAdapter<D, VH> {

        private int TYPE_CHECKBOX = 1;
        private int TYPE_CHECKBOX_GROUP = 2;

        public CheckboxGroupAdapter(RecyclerView recyclerView) {
            super(recyclerView);
        }

        @Override
        public int getItemCount() {
            if (adapter.getData() != null) {
                return adapter.getData().size() + checkboxGroupCount();
            }
            return 0;
        }

        @Override
        protected int getItemLayoutID(int viewType) {
            if (viewType == TYPE_CHECKBOX) {
                return getCheckBoxLayoutID();
            } else {
                return getCheckBoxGroupLayoutID();
            }
        }

        @Override
        protected VH createItemViewHolder(View itemView, int viewType) {
            return CheckboxGroupPopupWindow.this.createViewHolder(itemView);
        }

        @Override
        protected int getViewType(int position) {
            if (isCheckboxGroupItem(position)) {
                return TYPE_CHECKBOX_GROUP;
            } else {
                return TYPE_CHECKBOX;
            }
        }

        @Override
        protected void onBindItemViewHolder(VH holder, int position, int index, boolean isScrolling) {
            D item = adapter.getData().get(position);
            holder.bindView(adapter.getData().get(position), item.equals(selectedItem));
        }
    }


    static public abstract class CheckboxHolder<T> extends RecyclerViewHolder {
        public CheckboxHolder(View itemView) {
            super(itemView);
        }

        abstract protected void bindView(T data, boolean isCheck);
    }


    public interface onItemCheckedListener<D> {
        void onItemChecked(int position, D item);
    }

}
